package com.mobi.Survey.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;

import com.mobi.Survey.Messages;
import com.mobi.Survey.model.AbstractTable;
import com.mobi.Survey.model.AggregateResultTable;
import com.mobi.Survey.model.SubscriptionTable;
import com.mobi.Survey.model.SurveyDetailTable;
import com.mobi.Survey.model.SurveyResultTable;
import com.mobi.Survey.model.SurveyTable;
import com.mobi.Survey.utils.Helper;

/**
 * 
 * <b>Author:</b> Yahya Arshad
 * <p>
 * <b>Company:</b> Mobi Media Soft
 * <p>
 * <b> Website:</b> www.mobimediasoft.com
 * <p>
 * SurveyPojo.java This class hods data about an individual Survey
 */
public class SurveyPojo extends Pojo
{

	private String surveyKey;
	private long id;
	private String surveyDiscription;
	private String companyName;
	private String website;
	private String phone;
	private String contactEmail;
	private String subsEmail;

	private String txtBtnSurveyResult;
	private String txtBtnCorrectAnswer;
	private String txtBtnStartSurvey;

	private String iconAddress;
	private Bitmap bitmapIcon;

	private boolean showAllControls;

	private long subscriptionId;

	private SubscriptionPojo subscription;

	/*
	 * CR-3 To Control BG Image,Color and Font of Survey
	 */

	private String bGColor;
	private String bGImageUrl;
	private Bitmap bgImageBitmap;
	private String fontColor;

	/**
	 * @return the bgImageBitmap
	 */
	public Bitmap getBgImageBitmap()
	{
		return bgImageBitmap;
	}

	/**
	 * @param bgImageBitma
	 *            the bgImageBitma to set
	 */
	public void setBgImageBitmap(Bitmap bgImageBitmap)
	{
		this.bgImageBitmap = bgImageBitmap;
	}

	/**
	 * @return the bGColor
	 */
	public String getbGColor()
	{
		return bGColor;
	}

	/**
	 * @param bGColor
	 *            the bGColor to set
	 */
	public void setbGColor(String bGColor)
	{
		this.bGColor = bGColor;
	}

	/**
	 * @return the bGImageUrl
	 */
	public String getbGImageUrl()
	{
		return bGImageUrl;
	}

	/**
	 * @param bGImageUrl
	 *            the bGImageUrl to set
	 */
	public void setbGImageUrl(String bGImageUrl)
	{
		this.bGImageUrl = bGImageUrl;
	}

	/**
	 * @return the fontColor
	 */
	public String getFontColor()
	{
		return fontColor;
	}

	/**
	 * @param fontColor
	 *            the fontColor to set
	 */
	public void setFontColor(String fontColor)
	{
		this.fontColor = fontColor;
	}

	private List<SurveyDetailPojo> surveyDetail;

	public String getTxtBtnSurveyResult()
	{
		return txtBtnSurveyResult;
	}

	public String getTxtBtnCorrectAnswer()
	{
		return txtBtnCorrectAnswer;
	}

	public String getTxtBtnStartSurvey()
	{
		return txtBtnStartSurvey;
	}

	public void setTxtBtnSurveyResult(String txtBtnSurveyResult)
	{
		this.txtBtnSurveyResult = txtBtnSurveyResult;
	}

	public void setTxtBtnCorrectAnswer(String txtBtnCorrectAnswer)
	{
		this.txtBtnCorrectAnswer = txtBtnCorrectAnswer;
	}

	public void setTxtBtnStartSurvey(String txtBtnStartSurvey)
	{
		this.txtBtnStartSurvey = txtBtnStartSurvey;
	}

	public SubscriptionPojo getSubscription()
	{
		return subscription;
	}

	public void setSubscription(SubscriptionPojo subscription)
	{
		this.subscription = subscription;
	}

	public String getSubsEmail()
	{
		return subsEmail;
	}

	public void setSubsEmail(String subsEmail)
	{
		this.subsEmail = subsEmail;
	}

	public String getContactEmail()
	{
		return contactEmail;
	}

	public void setContactEmail(String contactEmail)
	{
		this.contactEmail = contactEmail;
	}

	public String getSurveyKey()
	{
		if (surveyKey == null)
			surveyKey = "";
		return surveyKey;
	}

	public long getId()
	{
		return id;
	}

	public long getSubscriptionId()
	{
		return subscriptionId;
	}

	public void setSubscriptionId(long subscriptionId)
	{
		this.subscriptionId = subscriptionId;
	}

	public String getSurveyDiscription()
	{
		return surveyDiscription;
	}

	public String getCompanyName()
	{
		return companyName;
	}

	public String getWebsite()
	{
		return website;
	}

	public String getPhone()
	{
		return phone;
	}

	public List<SurveyDetailPojo> getSurveyDetail()
	{

		if (surveyDetail == null)
			return new ArrayList<SurveyDetailPojo>();
		return surveyDetail;
	}

	public void setSurveyKey(String surveyKey)
	{
		this.surveyKey = surveyKey;
	}

	public void setId(long id)
	{
		this.id = id;
	}

	public void setSurveyDiscription(String surveyDiscription)
	{
		this.surveyDiscription = surveyDiscription;
	}

	public void setCompanyName(String companyName)
	{
		this.companyName = companyName;
	}

	public void setWebsite(String website)
	{
		this.website = website;
	}

	public void setPhone(String phone)
	{
		this.phone = phone;
	}

	public void setSurveyDetail(List<SurveyDetailPojo> surveyDetail)
	{
		this.surveyDetail = surveyDetail;
	}

	/**
	 * Clearing resources held by Survey
	 */
	public void dispose()
	{
		if (bitmapIcon != null && !bitmapIcon.isRecycled())
		{
			bitmapIcon.recycle();
			bitmapIcon = null;
		}
		if (surveyDetail != null)
			this.surveyDetail.clear();
		surveyDetail = null;
	}

	/**
	 * 
	 * @param ctx
	 * @param surveyPojo
	 *            set survey id of the survey for which to check if survey
	 *            already exist in database
	 * @return id greater than 0 if it already exist
	 */
	public static int isNew(Context ctx, SurveyPojo surveyPojo)
	{
		int id = -1;

		SurveyTable at = new SurveyTable(ctx);
		try
		{
			id = at.isNew(surveyPojo.getSurveyKey().trim());
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if (at != null)
			{
				at.closeDB();
				at = null;
			}

		}
		return id;

	}

	/**
	 * Deletes all table data from master and its child's tables
	 * 
	 * @param ctx
	 */

	public static void deleteAll(Context ctx)
	{

		AbstractTable at = new SurveyTable(ctx);
		at.deleteAllData();
		at.closeDB();

		at = new SurveyDetailTable(ctx);
		at.deleteAllData();
		at.closeDB();

		at = new SubscriptionTable(ctx);
		at.deleteAllData();
		at.closeDB();

		at = new AggregateResultTable(ctx);
		at.deleteAllData();
		at.closeDB();

		at = new SurveyResultTable(ctx);
		at.deleteAllData();
		at.closeDB();
		File file = new File(Environment.getExternalStorageDirectory()
				.getAbsolutePath(), Helper.APP_FOLDER);
		Helper.delete(file);

	}

	/**
	 * Delete a survey completely
	 * 
	 * @param id
	 *            of survey to delete
	 * @param ctx
	 * @return true if deleted successfully
	 */
	public static boolean deleteSurvey(long subsId, long id, Context ctx)
	{
		AbstractTable at = new SurveyTable(ctx);
		at.deleteRow(id);
		at.closeDB();
		at = new SurveyDetailTable(ctx);
		boolean is = false;
		try
		{
			is = at.deleteRow(id);

			// For subscription table we are checking if any more survey depend
			// upon this subscriber id if no more survey depend upon it we will
			// delete that subscription record too. because a subscription have
			// one to may relation with survey
			if (!((SurveyDetailTable) at).isSubscriptionExist(subsId))
			{
				at.closeDB();
				at = new SubscriptionTable(ctx);
				at.deleteRow(subsId);

			}
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{

			at.closeDB();
			at = null;

		}
		at = new SurveyResultTable(ctx);
		at.deleteRow(id);

		at.closeDB();

		return is;
	}

	/**
	 * 
	 * @param id
	 *            of survey to update
	 * @param survey
	 *            data for the survey to update
	 * @param ctx
	 * @return
	 */
	public static boolean updateSurvey(long id, SurveyPojo survey, Context ctx)
	{
		AbstractTable at = new SurveyTable(ctx);

		boolean is = false;
		try
		{
			is = ((SurveyTable) at).updateRow(id, survey);
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if (at != null)
			{
				at.closeDB();
				at = null;
			}
		}

		return is;
	}

	/**
	 * If user download a survey which already exist in database we shows a
	 * confirmation dialogue if he want to overwrite
	 * 
	 * @param id
	 *            of survey to overwrite
	 * @param ctx
	 * @param surveyPojo
	 */
	private static void showDeleteConfirmationDialogue(final long id,
			final Context ctx, final SurveyPojo surveyPojo)
	{
		final AlertDialog.Builder alert = new AlertDialog.Builder(ctx);

		alert.setTitle(Messages.DUPLICATE_SURVEY);
		alert.setMessage(Messages.DUPLICATE_SURVEY_DESC_MSG);

		alert.setPositiveButton("Yes", new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int whichButton)
			{
				if (updateSurvey(id, surveyPojo, ctx))
				{

					if (id > 0)
					{
						// SurveyPojo.commit(ctx, surveyPojo);
						List<SurveyDetailPojo> surveyDetails = surveyPojo
								.getSurveyDetail();

						AbstractTable at = new SurveyDetailTable(ctx);

						try
						{
							at.deleteRow(id);
						} catch (Exception e)
						{
							e.printStackTrace();
						} finally
						{
							if (at != null)
							{
								at.closeDB();
								at = null;
							}
						}

						SurveyDetailPojo.commit(ctx, surveyDetails, id);

						surveyDetails = null;

						// SubscriptionPojo.commit(ctx,
						// surveyPojo.getSubscription());
					}

					//
				}

			}
		});

		alert.setNegativeButton("No", new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int whichButton)
			{

			}
		});
		((Activity) ctx).runOnUiThread(new Runnable()
		{

			public void run()
			{
				alert.show();

			}
		});

	}

	public static int getTotalSurveys(Context ctx)
	{
		SurveyTable st = new SurveyTable(ctx);
		int total = st.getSurveyCount();
		st.closeDB();

		return total;

	}

	/**
	 * Save a survey in database to save a survey its id should be greater than
	 * 0 and survey detail control should be greater than 0 in number and its
	 * survey key should not be null
	 * 
	 * @param ctx
	 * @param surveyPojo
	 *            survey to save
	 * @return
	 */
	public static boolean commit(Context ctx, SurveyPojo surveyPojo)
	{
		AbstractTable at = null;
		long id = -1;

		try
		{

			at = new SurveyTable(ctx);

			id = isNew(ctx, surveyPojo);
			if (id > 0)
			{
				showDeleteConfirmationDialogue(id, ctx, surveyPojo);
			} else
			{
				id = at.insertRow(surveyPojo);
				if (id > 0)
				{

					List<SurveyDetailPojo> surveyDetails = surveyPojo
							.getSurveyDetail();

					SurveyDetailPojo.commit(ctx, surveyDetails, id);

					surveyDetails = null;

					SubscriptionPojo.commit(ctx, surveyPojo.getSubscription());

				} else
				{
					printConsoleMsg("Invalid Id Send");
				}

			}

		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if (at != null)
			{
				at.closeDB();
				at = null;
			}
		}

		return true;

	}

	/**
	 * 
	 * 
	 * @param ctx
	 * @param surveyPojos
	 *            Collection of surveys to save
	 * @return
	 */
	public static boolean commit(Context ctx, List<SurveyPojo> surveyPojos)
	{
		AbstractTable at = null;
		long id = -1;
		// boolean is = false;
		try
		{

			at = new SurveyTable(ctx);
			for (SurveyPojo surveyPojo : surveyPojos)
			{
				id = isNew(ctx, surveyPojo);
				String address = surveyPojo.getIconAddress();

				if (address != null && address.length() > 0)
				{
					Helper.downloadFile(
							address,
							Helper.getTempFile(Helper
									.getHashNameFromUrl(address) + ""));
				}
				if (id > 0)
				{
					showDeleteConfirmationDialogue(id, ctx, surveyPojo);
				} else
				{
					id = at.insertRow(surveyPojo);
					if (id > 0)
					{
						// is = true;
						List<SurveyDetailPojo> surveyDetails = surveyPojo
								.getSurveyDetail();

						SurveyDetailPojo.commit(ctx, surveyDetails, id);

						surveyDetails = null;

						SubscriptionPojo.commit(ctx,
								surveyPojo.getSubscription());

					}
				}

			}

		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if (at != null)
			{
				at.closeDB();
				at = null;
			}
		}

		return true;

	}

	/**
	 * 
	 * 
	 * @param ctx
	 * @param surveyPojos
	 *            Collection of surveys to save
	 * @return
	 */
	public static boolean commitAll(Context ctx, List<SurveyPojo> surveyPojos)
	{
		AbstractTable at = null;
		long id = -1;
		// boolean is = false;
		try
		{

			at = new SurveyTable(ctx);
			for (SurveyPojo surveyPojo : surveyPojos)
			{
				id = isNew(ctx, surveyPojo);
				String address = surveyPojo.getIconAddress();

				if (address != null && address.length() > 0)
				{
					try
					{
						if (!new File(Helper.getTempFile(Helper
								.getHashNameFromUrl(address) + "")).exists())
							Helper.downloadFile(
									address,
									Helper.getTempFile(Helper
											.getHashNameFromUrl(address) + ""));
					} catch (Exception ex)
					{
						Log.e(SurveyPojo.class.getSimpleName(),
								"Error: " + ex.getMessage() + " " + address);
					}

				}
				if (id > 0)
				{

					try
					{
						at.deleteRow(id);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
				} else
				{
					id = at.insertRow(surveyPojo);
					if (id > 0)
					{
						// is = true;
						List<SurveyDetailPojo> surveyDetails = surveyPojo
								.getSurveyDetail();

						SurveyDetailPojo.commit(ctx, surveyDetails, id);

						surveyDetails = null;

						SubscriptionPojo.commit(ctx,
								surveyPojo.getSubscription());

					}
				}

			}

		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if (at != null)
			{
				at.closeDB();
				at = null;

			}
			System.gc();
		}

		return true;

	}

	public static int getSurveyIdByKey(Context ctx, String sKey)
	{

		AbstractTable at = new SurveyTable(ctx);
		int id = ((SurveyTable) at).getSurveyIdByKey(sKey);

		at.closeDB();
		return id;

	}

	public String getIconAddress()
	{
		return iconAddress;
	}

	public void setIconAddress(String iconAddress)
	{
		this.iconAddress = iconAddress;
	}

	public Bitmap getBitmapIcon()
	{
		return bitmapIcon;
	}

	public void setBitmapIcon(Bitmap bitmapIcon)
	{
		this.bitmapIcon = bitmapIcon;
	}

	/**
	 * <p>
	 * If true all show all controls on single page otherwise will be displayed
	 * in pagination (user have to press next to go to next control)
	 * </p>
	 * 
	 * @return
	 */
	public boolean isShowAllControls()
	{
		return showAllControls;
	}

	/**
	 * <p>
	 * If true all show all controls on single page otherwise will be displayed
	 * in pagination (user have to press next to go to next control)
	 * </p>
	 * 
	 * @return
	 */
	public void setShowAllControls(boolean showAllControls)
	{
		this.showAllControls = showAllControls;
	}

}
